﻿using DimensionsHelper.Common.Contracts.TableFormatter.Options;

namespace DimensionsHelper.Client.WinUi.ViewModels;

public partial class SigComparisonViewModel : ObservableObject
{
    public static readonly string[] MarkTypeNames;


    private bool _updatingInternal;


    static SigComparisonViewModel()
    {
        MarkTypeNames = TypeHelper.ReadEnumMembersDescription<SigComparisonMarkType>().Keys.ToArray();
    }


    public SigComparisonViewModel()
    {
        PropertyChanged += SigComparisonViewModel_PropertyChanged;
        Expression = string.Empty;
        MarkTypeName = MarkTypeNames[0];
        StartStringToSkip = string.Empty;
        MarkAtFirstColumn = true;
        KeepLeftBorderOnConflict = true;
        KeepTopBorderOnConflict = true;
        CharAtMarkColumnColor = Colors.Black;
        CharAtAnotherColumnColor = Colors.Black;
    }


    public SigComparisonMapViewModel? Map
    {
        get;
        init;
    }

    [ObservableProperty]
    public partial Color CharAtMarkColumnColor
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial Color CharAtAnotherColumnColor
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial string Expression
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial bool MarkAtFirstColumn
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial bool MarkAtAnotherColumn
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial string MarkTypeName
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial SigComparisonMarkType MarkType
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial string StartStringToSkip
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial bool KeepTopBorderOnConflict
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial bool KeepLeftBorderOnConflict
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial bool KeepRightBorderOnConflict
    {
        get;
        set;
    }


    [ObservableProperty]
    public partial bool KeepBottomBorderOnConflict
    {
        get;
        set;
    }

    private void SigComparisonViewModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        if (_updatingInternal)
        {
            return;
        }

        _updatingInternal = true;

        switch (e.PropertyName)
        {
            case nameof(MarkType):
            {
                MarkTypeName = MarkTypeNames[(int)MarkType];
                break;
            }

            case nameof(MarkTypeName):
            {
                MarkType = (SigComparisonMarkType)Array.IndexOf(MarkTypeNames, MarkTypeName);
                break;
            }

            case nameof(MarkAtFirstColumn):
            {
                MarkAtAnotherColumn = !MarkAtFirstColumn;
                break;
            }

            case nameof(MarkAtAnotherColumn):
            {
                MarkAtFirstColumn = !MarkAtAnotherColumn;
                break;
            }
        }

        _updatingInternal = false;
    }


    public void SetOperationsOnConflict(SigComparisonBorderMarkConflictFlags flags)
    {
        if (flags.HasFlag(SigComparisonBorderMarkConflictFlags.Left))
        {
            KeepLeftBorderOnConflict = true;
        }

        if (flags.HasFlag(SigComparisonBorderMarkConflictFlags.Top))
        {
            KeepTopBorderOnConflict = true;
        }

        if (flags.HasFlag(SigComparisonBorderMarkConflictFlags.Right))
        {
            KeepRightBorderOnConflict = true;
        }

        if (flags.HasFlag(SigComparisonBorderMarkConflictFlags.Bottom))
        {
            KeepBottomBorderOnConflict = true;
        }
    }


    public SigComparisonBorderMarkConflictFlags GetOperationsOnConflict()
    {
        SigComparisonBorderMarkConflictFlags flags = SigComparisonBorderMarkConflictFlags.Default;

        if (KeepLeftBorderOnConflict)
        {
            flags |= SigComparisonBorderMarkConflictFlags.Left;
        }

        if (KeepTopBorderOnConflict)
        {
            flags |= SigComparisonBorderMarkConflictFlags.Top;
        }

        if (KeepRightBorderOnConflict)
        {
            flags |= SigComparisonBorderMarkConflictFlags.Right;
        }

        if (KeepBottomBorderOnConflict)
        {
            flags |= SigComparisonBorderMarkConflictFlags.Bottom;
        }

        return flags;
    }


    [RelayCommand]
    private void Remove() => Map?.Remove(this);


    public void JoinExpression(string expression)
    {
        if (string.IsNullOrEmpty(Expression))
        {
            Expression = expression;
        }
        else
        {
            Expression += "," + expression;
        }
    }
}